home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / Snippets / Processes / KillEveryOneButMe / KillEveryOneButMe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-13  |  20.2 KB  |  565 lines  |  [TEXT/MPS ]

  1. /* KillEveryBodyButMe.c */
  2. /* Some folks want to kill all the other applications running on a machine */
  3. /* for demos, school situations, kiosks, etc. */
  4. /* with System 7, it's easy, just use the Process Manager and AppleEvents. */
  5. /* This thing shows you how. */
  6. /* PLEASE don't abuse this.  System 7 gives the user full-time multiFinder, and they */
  7. /* like it, our System Software team worked very hard to make this */
  8. /* happen.  ONLY do this in very special circumstances, or you're taking */
  9. /* power away from the user and weaking the strength of the Mac. */
  10. /* Written  by C.K. Haun <TR> */
  11. /* Apple Developer Tech Support */
  12.  
  13. /* BUG FIX, if only this app and the Finder were/was running, it didn't do anything */
  14. /* Ooops */
  15.  
  16. /* Of course, Copyright 1991-1992, Apple Computer Inc. */
  17. #include <Types.h>
  18. #include <memory.h>
  19. #include <Packages.h>
  20. #include <Errors.h>
  21. #include <quickdraw.h>
  22. #include <fonts.h>
  23. #include <dialogs.h>
  24. #include <windows.h>
  25. #include <menus.h>
  26. #include <events.h>
  27. #include <OSEvents.h>
  28. #include <Desk.h>
  29. #include <diskinit.h>
  30. #include <OSUtils.h>
  31. #include <resources.h>
  32. #include <toolutils.h>
  33. #include <AppleEvents.h>
  34. #include <EPPC.h>
  35. #include <GestaltEqu.h>
  36. #include <PPCToolbox.h> 
  37. #include <Processes.h>
  38. #include <Balloons.h>
  39. /* prototypes */
  40. void InitalizeApp(void);
  41. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  42. void DrawMain(WindowPtr drawIt);
  43. Boolean DoSelected(long val);
  44.  
  45. void InitAEStuff(void);
  46. void DoHighLevel(EventRecord *AERecord);
  47. void DoDaCall(MenuHandle themenu, long theit);
  48. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  49. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  50. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  51. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  52. void SampleHelpDialog(void);
  53. void KillEveryBody(void);
  54. /* one external */
  55. extern void _DataInit();                                    /* this is the C initialization code */
  56.  
  57. #define kMBarID 128
  58. #define kAppleMenu 128
  59. #define kFileMenu 129
  60. #define kEditMenu 130
  61. #define kToolsMenu 131
  62. #define kResumeMask             1       /* bit of message field for resume vs. suspend */
  63. #define kSampHelp 129
  64. #define kAboutBox 128
  65. #define kHelpString 128
  66. #define kNewItem 1
  67. #define kOpenItem 2
  68. #define kCloseItem 3
  69. #define kSaveItem 4
  70. #define kSaveAsItem 5
  71. #define kFileBlank1 6
  72. #define kPageSetupItem 7
  73. #define kPrintItem 8
  74. #define kFileBlank2 9
  75. #define kQuitItem 10
  76. #define kBadSystem 130
  77. #define kTitle 129
  78.  
  79. Handle gMymenu;                                             /* my menu bar handle */
  80. MenuHandle gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gToolMenuHandle;
  81. Boolean gQuit, gInBackground;
  82. EventRecord gERecord;
  83. AEDesc gTheAddress;
  84. WindowPtr myWindow;
  85. ProcessSerialNumber gOurSN;
  86. short gHelpItem;
  87.  
  88. #ifdef powerc
  89.    QDGlobals    qd;
  90. #endif
  91.  
  92. #pragma segment Main
  93. main()
  94. {
  95.     WindowPtr twindow;
  96.     UnloadSeg((Ptr)_DataInit);                              /* throw out setup code */
  97.     InitalizeApp();
  98.     UnloadSeg((Ptr)InitalizeApp);                           /* get rid of my initialization code */
  99.     do {
  100.         WaitNextEvent(everyEvent, &gERecord, 30, nil);
  101.         switch (gERecord.what) {
  102.             
  103.             case nullEvent:
  104.                 /* no nul processing in this sample */
  105.                 break;
  106.             case updateEvt:
  107.                 DrawMain((WindowPtr)gERecord.message);      /* draw whatever window needs an update */
  108.                 break;
  109.             case mouseDown:
  110.                 /* first see where the hit was */
  111.                 switch (FindWindow(gERecord.where, &twindow)) {
  112.                     
  113.                     case inDesk:                            /* if they hit in desk, then the process manager */
  114.                         break;                              /* will switch us out, we don't need to do anything */
  115.                     case inMenuBar:
  116.                         DoSelected(MenuSelect(gERecord.where));
  117.                         break;
  118.                         
  119.                     case inSysWindow:
  120.                         /* pass to the system */
  121.                         SystemClick(&gERecord, twindow);
  122.                         break;
  123.                     case inContent:
  124.                         /* Handle content and control clicks here */
  125.                         break;
  126.                     case inDrag:
  127.                         if (twindow == FrontWindow())
  128.                             DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
  129.                         break;
  130.                     case inGrow:
  131.                         /* Call GrowWindow here if you have a grow box */
  132.                         break;
  133.                     case inGoAway:
  134.                         /* Click in Close box */
  135.                         break;
  136.                         
  137.                 }
  138.             case mouseUp:
  139.                 /* don't care */
  140.                 break;
  141.                 /* same action for key or auto key */
  142.             case keyDown:
  143.             case autoKey:
  144.                 if (gERecord.modifiers & cmdKey)
  145.                     DoSelected(MenuKey(gERecord.message & charCodeMask));
  146.                 break;
  147.             case keyUp:
  148.                 /* don't care */
  149.                 break;
  150.             case diskEvt:
  151.                 /* I don't do anything special for disk events, this just passes them */
  152.                 /* to a function that checks for an error on the mount */
  153.                 DoDiskEvents(gERecord.message);
  154.                 break;
  155.             case activateEvt:
  156.                 if (gERecord.modifiers & activeFlag){
  157.                     SetPort(myWindow);
  158.                     DrawMain((WindowPtr)gERecord.message);
  159.                     }
  160.                 break;
  161.             case networkEvt:
  162.                 /* don't care */
  163.                 break;
  164.             case driverEvt:
  165.                 /* don't care */
  166.                 break;
  167.             case app4Evt:
  168.                 switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  169.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  170.                         gInBackground = (gERecord.message & kResumeMask) == 0;
  171.                         break;
  172.                 }
  173.                 break;
  174.             default:
  175.                 break;
  176.                 /* This dispatches high level events (AppleEvents, for example) */
  177.                 /* to our dispatch routine.  This is NEW in the event loop for */
  178.                 /* System 7 */
  179.             case kHighLevelEvent:
  180.                 DoHighLevel(&gERecord);
  181.                 break;
  182.                 
  183.         }
  184.     }
  185.             while (gQuit != true);
  186.     
  187. }
  188.  
  189. /* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
  190. /* like to perform some action or just know when a DA is opened in your */
  191. /* layer.  Can be handy to track memory problems when a DA is opened */
  192. /* with an Option-open */
  193. void DoDaCall(MenuHandle themenu, long theit)
  194. {
  195.     long qq;
  196.     char DAname[255];
  197.     GetItem(themenu, theit, &DAname);
  198.     qq = OpenDeskAcc(DAname);
  199. }
  200.  
  201. /* end DoDaCall */
  202.  
  203. /* DoDiskEvents just checks the error code from the disk mount, */
  204. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  205. /* You can do much more here if you care about what disks are */
  206. /* in the drive */
  207. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  208. {
  209.     short hival, loval, tommy;
  210.     Point fredpoint =  {
  211.         40, 40
  212.     };
  213.     hival = HiWord(dinfo);
  214.     loval = LoWord(dinfo);
  215.     if (hival != noErr)                                     /* something happened */ {
  216.         tommy = DIBadMount(fredpoint, dinfo);
  217.     }
  218. }
  219.  
  220. /* draws my window.  Pretty simple */
  221. void DrawMain(WindowPtr drawIt)
  222. {
  223.     short vPos, hPos;
  224.     short incre = 20;
  225.     short oldFace;
  226.     ProcessInfoRec infoRec;
  227.     StringHandle theString;
  228.     OSErr myErr;
  229.     Str31 processName;
  230.     FSSpec procSpec;
  231.     ProcessSerialNumber processSN;
  232.     processSN.lowLongOfPSN = kNoProcess;
  233.     processSN.highLongOfPSN = kNoProcess;
  234.     vPos = 15;
  235.     hPos = 20;
  236.     BeginUpdate(drawIt);
  237.     SetPort(drawIt);
  238.     EraseRect(&drawIt->portRect);
  239.     MoveTo(hPos, vPos);
  240.     theString = GetString(kTitle);
  241.     HLock((Handle)theString);
  242.     oldFace = drawIt->txFace;
  243.     TextFace(bold);
  244.     DrawString((ConstStr255Param)*theString);
  245.     TextFace(oldFace);
  246.     ReleaseResource((Handle)theString);
  247.     vPos += incre;
  248.     do {
  249.         myErr = GetNextProcess(&processSN);
  250.         
  251.         infoRec.processInfoLength = sizeof(ProcessInfoRec);
  252.         infoRec.processName = &processName;
  253.         infoRec.processAppSpec = &procSpec;
  254.         myErr = GetProcessInformation(&processSN, &infoRec);
  255.         if (!myErr) {
  256.             MoveTo(hPos, vPos);
  257.             DrawString(infoRec.processName);
  258.             vPos += incre;
  259.         }
  260.     }
  261.             while (myErr == noErr);
  262.     
  263.     EndUpdate(drawIt);
  264. }
  265.  
  266. /* my menu action taker.  It returns a Boolean which I usually ignore, but it */
  267. /* mught be handy someday */
  268. Boolean DoSelected(long val)
  269. {
  270.     short loval, hival;
  271.     Boolean returnVal = false;
  272.     loval = LoWord(val);
  273.     hival = HiWord(val);
  274.     
  275.     switch (hival) {                                        /* switch off the menu number selected */
  276.         case kAppleMenu:                                    /* Apple menu */
  277.             if (loval != 1) {                               /* if this was not About, it's a DA */
  278.                 DoDaCall(gAppleMenuHandle, loval);
  279.             } else {
  280.                 Alert(kAboutBox, nil);                      /* do about box */
  281.             }
  282.             returnVal = true;
  283.             break;
  284.         case kFileMenu:                                     /* File menu */
  285.             switch (loval) {
  286.                 case kQuitItem:
  287.                     gQuit = true;                           /* only  item */
  288.                     returnVal = true;
  289.                     break;
  290.                 default:
  291.                     break;
  292.             }
  293.             break;
  294.         case kEditMenu:
  295.             /* edit menu junk */
  296.             /* don't care */
  297.             break;
  298.         case kToolsMenu:
  299.             /* add all your test stuff here */
  300.             /* only one item, kill stuff */
  301.             KillEveryBody();
  302.             InvalRect(&myWindow->portRect);
  303.             break;
  304.         case kHMHelpMenuID:                                 /* Defined in Balloons.h */
  305.             /* I only care about this item.  If anything else is returned here, I don't know what */
  306.             /* it is, so I leave it alone.  Remember, the Help Manager chapter says that */
  307.             /* Apple reserves the right to add and change things in the Help menu */
  308.             if (loval == gHelpItem)
  309.                 SampleHelpDialog();
  310.             break;
  311.             
  312.     }
  313.     HiliteMenu(0);
  314.     return(returnVal);
  315. }
  316.  
  317. /* InitAEStuff installs my appleevent handlers */
  318. void InitAEStuff(void)
  319. {    
  320.     OSErr aevtErr = noErr;
  321.     long aLong = 0;
  322.     Boolean gHasAppleEvents = false;
  323.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  324.     *   then we exit */
  325.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  326.     /* The following series of calls installs all our AppleEvent Handlers.
  327.     *   These handlers are added to the application event handler list that 
  328.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  329.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  330.     *   list of handlers and dispatch to it if there is one.
  331.     */
  332.     if (gHasAppleEvents) {
  333.          aevtErr = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, 
  334.              NewAEEventHandlerProc(AEOpenHandler),0, false);
  335.              if (aevtErr)  ExitToShell();
  336.              
  337.          aevtErr = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, 
  338.              NewAEEventHandlerProc(AEOpenDocHandler),0, false);
  339.              if (aevtErr)  ExitToShell();
  340.  
  341.          aevtErr = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, 
  342.              NewAEEventHandlerProc(AEQuitHandler), 0, false);
  343.              if (aevtErr)  ExitToShell();
  344.  
  345.          aevtErr = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, 
  346.              NewAEEventHandlerProc(AEPrintHandler),0, false);
  347.              if (aevtErr)  ExitToShell();
  348.  
  349.          if (aevtErr)  ExitToShell();
  350.          
  351.        } 
  352.     else ExitToShell();
  353.     
  354. }
  355. /* end InitAEStuff */
  356.  
  357.  
  358.  
  359. /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
  360. /* easy for me to say, huh? */
  361. void DoHighLevel(EventRecord *AERecord)
  362. {
  363.     
  364.     AEProcessAppleEvent(AERecord);
  365.     
  366. }
  367.  
  368. /* end DoHighLevel */
  369.  
  370. /* This is the standard Open Application event.  */
  371. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  372. {
  373. #pragma unused (messagein,reply,refIn)
  374.     /* we of course don't do anything here in this simple app */
  375.     /* except open our window */
  376.     myWindow = GetNewWindow(128, nil, (WindowPtr)-1);
  377.     SetPort(myWindow);
  378.     return(noErr);
  379. }
  380.  
  381. /* end AEOpenHandler */
  382.  
  383. /* Open Doc, opens our documents.  Remember, this can happen at application start AND */
  384. /* anytime else.  If your app is up and running and the user goes to the desktop, hilites one */
  385. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  386. /* handler will get called. Which means you don't do any initialization of globals here, or */
  387. /* anything else except open then doc.  */
  388. /* SO-- Do NOT assume that you are at app start time in this */
  389. /* routine, or bad things will surely happen to you. */
  390.  
  391. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  392. {
  393. #pragma unused (messagein,refIn,reply)
  394.     /* we of course don't do anything here */
  395.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  396. }
  397.  
  398. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  399. {                                                           /* no printing handler in yet, so we'll ignore this */
  400.     /* the operation is functionally identical to the ODOC event, with the additon */
  401.     /* of calling your print routine.  */
  402. #pragma unused (messagein,refIn,reply)
  403.     /* we of course don't do anything here */
  404.     return(errAEEventNotHandled);                           /* we have no docs, so no pdoc events should come to us */
  405. }
  406.  
  407. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.  */
  408. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.  */
  409. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  410. {
  411. #pragma unused (messagein,refIn,reply)
  412.     
  413.     /* prepQuit sets the Stop flag for us.  It does _NOT_ quit, you */
  414.     /* should NEVER quit from an AppleEvent handler.  Calling */
  415.     /* ExitToShell here would blow things up */
  416.     gQuit = true;
  417.     return(noErr);
  418. }
  419.  
  420.  
  421. /* This is my sample help dialog.  Does not do anything, expand as you need */
  422. void SampleHelpDialog(void)
  423. {
  424.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  425.     short itemhit = 0;
  426.     while (itemhit != 1) {
  427.         ModalDialog(nil, &itemhit);
  428.     }
  429.     DisposDialog(tdial);
  430. }
  431.  
  432.  
  433. /* This is the killer code.  It finds and kills every other  */
  434. /* application on your machine. */
  435. void KillEveryBody(void)
  436. {
  437.     ProcessSerialNumber myProc, processSN;
  438.     ProcessSerialNumber finderPSN;
  439.     ProcessInfoRec infoRec;
  440.     Str31 processName;
  441.     FSSpec procSpec;
  442.     
  443.     OSErr myErr = noErr;
  444.     OSErr otherError;
  445.     AppleEvent theEvent;
  446.     AEDesc theAddress;
  447.     Boolean ourFlag, notFinder;
  448.     Boolean finderFound = false;
  449.     GetCurrentProcess(&myProc);
  450.     /* Preset the PSN to no PSN, see IM VI, the Process Manager */
  451.     processSN.lowLongOfPSN = kNoProcess;
  452.     processSN.highLongOfPSN = kNoProcess;
  453.     finderPSN.lowLongOfPSN = nil;
  454.     finderPSN.highLongOfPSN = nil;
  455.     
  456.     do {
  457.         myErr = GetNextProcess(&processSN);
  458.         /* See if it's us first */
  459.         notFinder = true;
  460.         SameProcess(&myProc, &processSN, &ourFlag);
  461.  
  462.             infoRec.processInfoLength = sizeof(ProcessInfoRec);
  463.             infoRec.processName = &processName;
  464.             infoRec.processAppSpec = &procSpec;
  465.             GetProcessInformation(&processSN, &infoRec);
  466.         if (!ourFlag && !finderFound) {
  467.             /* see if it's the Finder, we have to kill the finder LAST */
  468.             /* or else non-sys 7 apps won't get killed */
  469.             /* since the Finder must be there to convert the AppleEvent to Puppet Strings */
  470.             /* if the app is not APpleEvent aware */
  471.             /* Also, FileShare HAS to be killed before the Finder */
  472.             /* or your life will be unpleasant */
  473.  
  474.             if (infoRec.processSignature == 'MACS' && infoRec.processType == 'FNDR') {
  475.                 /* save this number for later  */
  476.                 finderPSN = processSN;
  477.                 notFinder = false;
  478.                 finderFound = true;
  479.             
  480.             } else {
  481.                 notFinder = true;
  482.             }
  483.         }
  484.         if (!myErr && !ourFlag && notFinder) {
  485.             otherError = AECreateDesc(typeProcessSerialNumber, (Ptr)&processSN, sizeof(processSN), &theAddress);
  486.             if (!otherError)
  487.                 otherError = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &theAddress, kAutoGenerateReturnID,
  488.                                                 kAnyTransactionID, &theEvent);
  489.             if (!otherError)
  490.                 AEDisposeDesc(&theAddress);
  491.             /* Again, the Finder will convert the AppleEvent to puppetstrings if */
  492.             /* the application is a System 6 or non-AE aware app.  This ONLY  */
  493.             /* happens for the 4 required (oapp,odoc,pdoc, and quit) AppleEvents  */
  494.             /* and ONLY if you use the PSN for the address */
  495.             if (!otherError)
  496.                 AESend(&theEvent, nil, kAENoReply + kAEAlwaysInteract + kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout,
  497.                        nil, nil);
  498.             AEDisposeDesc(&theEvent);
  499.         }
  500.     } while (!myErr);
  501.     
  502.     /* Now, if the finder was running, it's safe to kill it */
  503.     if (finderPSN.lowLongOfPSN || finderPSN.highLongOfPSN) {
  504.         otherError = AECreateDesc(typeProcessSerialNumber, (Ptr)&finderPSN, sizeof(processSN), &theAddress);
  505.         if (!otherError)
  506.             otherError = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &theAddress, kAutoGenerateReturnID,
  507.                                             kAnyTransactionID, &theEvent);
  508.         if (!otherError)
  509.             AEDisposeDesc(&theAddress);
  510.         if (!otherError)
  511.             AESend(&theEvent, nil, kAENoReply + kAEAlwaysInteract + kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil,
  512.                    nil);
  513.         AEDisposeDesc(&theEvent);
  514.     }
  515. }
  516.  
  517.  
  518.  
  519. #pragma segment Initialize
  520. void InitalizeApp(void)
  521. {
  522.     MenuHandle helpHandle;
  523.     StringHandle helpString;
  524.     short count;
  525.     long vers;
  526.     MaxApplZone();
  527.     InitGraf((Ptr)&qd.thePort);
  528.     InitFonts();
  529.     InitWindows();
  530.     InitMenus();
  531.     TEInit();
  532.     InitDialogs(nil);
  533.     InitCursor();
  534.     /* Check system version */
  535.     Gestalt(gestaltSystemVersion, &vers);
  536.     vers = (vers >> 8) & 0xf;                               /* shift result over and mask out major version number */
  537.     if (vers < 7) {
  538.         StopAlert(kBadSystem, nil);
  539.         ExitToShell();
  540.     }
  541.     InitAEStuff();
  542.     /* set up my menu junk */
  543.     gMymenu = GetNewMBar(kMBarID);
  544.     SetMenuBar(gMymenu);
  545.     gAppleMenuHandle = GetMHandle(kAppleMenu);
  546.     gFileMenuHandle = GetMHandle(kFileMenu);
  547.     gEditMenuHandle = GetMHandle(kEditMenu);
  548.     gToolMenuHandle = GetMHandle(kToolsMenu);
  549.     AddResMenu(gAppleMenuHandle, 'DRVR');
  550.     /* now install my Help menu item in the Help Manager's menu */
  551.     HMGetHelpMenuHandle(&helpHandle);                       /* Get the Hlpe menu handle */
  552.     count = CountMItems(helpHandle);                        /* How many items are there? */
  553.     helpString = GetString(kHelpString);                    /* get my help string */
  554.     DetachResource(helpString);                             /* detach it */
  555.     HNoPurge(helpString);
  556.     MoveHHi((Handle)helpString);
  557.     HLock((Handle)helpString);
  558.     InsMenuItem(helpHandle, (Ptr)*helpString, count + 1);       /* insert my item in the Help menu */
  559.     gHelpItem = CountMItems(helpHandle);                    /* The number of the item */
  560.     
  561.     DrawMenuBar();
  562.     GetCurrentProcess(&gOurSN);                             /* Get our process serial number for later use, if needed */
  563.     
  564. }
  565.